<template>
  <div class="container">
    <h1 class="title">Vue3 Waterfall Demo</h1>
    <div class="controls">
      <button @click="addItems" :disabled="loading" class="load-more-btn">
        <span v-if="!loading">加载更多</span>

        <span v-else class="loading-spinner"></span>
      </button>
      <button class="clear-reload-btn" @click="forceUpdate">强制更新</button>
      <button @click="clearAndReload" class="clear-reload-btn">
        清空并重新加载
      </button>
    </div>
    <div v-infinite-scroll="loadMore">
      <Waterfall
        ref="waterfall"
        :list="imageList"
        :width="300"
        :gutter="16"
        :columns="4"
        img-selector="url"
        animation-effect="fadeIn"
        :animation-duration="1000"
        :animation-delay="300"
        background-color="#f5f5f5"
      >
        <template #item="{ item }">
          <div class="card">
            <div class="image-wrapper">
              <LazyImg
                :url="item.url"
                :previewSrcList="[item.url]"
                :previewIcon="previewIcon"
                :hideOnClickModal="true"
              />
              <!-- <div class="overlay">
                            <span class="zoom-icon">🔍</span>
                        </div> -->
            </div>
            <div class="card-content">
              <h3>{{ item.title }}</h3>
              <p>{{ item.description }}</p>
              <div class="card-footer">
                <span class="likes">❤️ {{ item.likes }}</span>
                <span class="views">👁️ {{ item.views }}</span>
              </div>
            </div>
          </div>
        </template>
      </Waterfall>
    </div>
  </div>
</template>

<script setup lang="ts">
import _ from "lodash";
import { ref } from "vue";
import { Waterfall, LazyImg } from "../../lib/index";
import previewIcon from "../assets/previewIcon.png";

declare module "vue" {
  interface HTMLAttributes {
    "v-infinite-scroll"?: () => void;
  }
}
interface ImageItem {
  id: number;
  url: string;
  title: string;
  description: string;
  likes: number;
  views: number;
}

const baseImages: ImageItem[] = [
  {
    id: 1,
    url: new URL(`../assets/image.png`, import.meta.url).href,
    title: "工作室风景",
    description: "工作室的风景，充满着创意与灵感",
    likes: 128,
    views: 356,
  },
  {
    id: 2,
    url: new URL(`../assets/01.jpg`, import.meta.url).href,
    title: "飞行员兔子",
    description: "一只可爱的飞行员兔子,喜欢吗？",
    likes: 245,
    views: 589,
  },
  {
    id: 3,
    url: new URL(`../assets/book.jpg`, import.meta.url).href,
    title: "书籍",
    description: "HarmonyOS NEXT  原生开发之旅",
    likes: 167,
    views: 423,
  },
  {
    id: 4,
    url: new URL(`../assets/str.png`, import.meta.url).href,
    title: "树莓,莓",
    description: "据说树莓含有大量的营养成分是真的么??",
    likes: 198,
    views: 467,
  },
  {
    id: 5,
    url: new URL(`../assets/animate.png`, import.meta.url).href,
    title: "动物世界",
    description: "可爱有趣的动物们，带来欢乐与温暖",
    likes: 312,
    views: 678,
  },
];

const imageList = ref<ImageItem[]>(baseImages);
const loading = ref(false);
const waterfall = ref<any>(null);
/**
 * 强制更新瀑布流布局
 * 通过调用瀑布流组件的renderer方法来重新计算和更新布局
 * 在图片加载完成或需要手动更新布局时调用
 */
const forceUpdate = () => {
  waterfall.value.renderer();
};

/**
 * 清空并重新加载数据
 * 通过调用瀑布流组件的clearAndReload方法来清空当前数据并重新加载
 * 适用于需要完全重置瀑布流状态的场景，如切换数据源或重新排序
 */
const clearAndReload = () => {
  waterfall.value.clearAndReload();
};
const addItems = async () => {
  loading.value = true;

  const newItems = baseImages.map((item, index) => ({
    ...item,
    id: imageList.value.length + index + 1,
    url: `${item.url}?random=${Date.now()}-${index}`,
    likes: Math.floor(Math.random() * 500),
    views: Math.floor(Math.random() * 1000),
  }));
  imageList.value.push(...newItems);
  loading.value = false;
};
const loadMore = _.debounce(
  () => {
    addItems();
  },
  1000,
  {
    leading: true,
    trailing: false,
  }
);
</script>

<style scoped>
.container {
  max-width: 1400px;
  margin: 0 auto;
  padding: 20px;
}

.title {
  text-align: center;
  margin-bottom: 20px;
  color: #333;
  font-size: 2.5em;
  font-weight: bold;
}

.controls {
  text-align: center;
  margin-bottom: 20px;
}

.load-more-btn {
  padding: 12px 24px;
  background-color: #4caf50;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-size: 16px;
  transition: all 0.3s ease;
  position: relative;
  min-width: 120px;
}

.load-more-btn:hover {
  background-color: #45a049;
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.load-more-btn:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.clear-reload-btn {
  margin-left: 10px;
  padding: 12px 24px;
  background-color: #ff4757;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-size: 16px;
  transition: all 0.3s ease;
}

.clear-reload-btn:hover {
  background-color: #ff6b81;
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.loading-spinner {
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  border-top-color: white;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.card {
  border-radius: 12px;
  overflow: hidden;
  background: white;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
  cursor: pointer;
}

.card:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}

.image-wrapper {
  position: relative;
  overflow: hidden;
}

.image-wrapper img {
  width: 100%;
  display: block;
  transition: transform 0.3s ease;
}

.overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.card:hover .overlay {
  opacity: 1;
}

.card:hover .image-wrapper img {
  transform: scale(1.1);
}

.zoom-icon {
  font-size: 2em;
  color: white;
}

.card-content {
  padding: 16px;
}

.card-content h3 {
  margin: 0 0 8px;
  color: #333;
  font-size: 1.2em;
  font-weight: bold;
}

.card-content p {
  margin: 0 0 12px;
  color: #666;
  font-size: 0.9em;
  line-height: 1.5;
}

.card-footer {
  display: flex;
  justify-content: space-between;
  color: #888;
  font-size: 0.9em;
}

.likes,
.views {
  display: flex;
  align-items: center;
  gap: 4px;
}
</style>
